//
//  EPTransaction.m
//  ORM
//
//  Created by PH on 4.2.10.
//  Copyright 2010 Codesign. All rights reserved.
//

#import "EPTransaction.h"
#import "EPEnvironment.h"
#import "EPNil.h"

@implementation EPTransaction

- (id)initWithTransaction:(EXTransaction*)_transaction environment:(EPEnvironment*)_environment {
	if ((self = [super init])) {
		transaction = [_transaction retain];
		changedObjects = [[NSMutableSet alloc] init];
		oldValues = [[NSMutableDictionary alloc] init];
		environment = _environment;
	}
	return self;
}

- (void)commit {
	for (id object in changedObjects) {
		//NSLog(@"Should store object: %@", object);
		[transaction storeObject: object];
	}
	[[transaction retain] autorelease];
	environment.transaction = nil;
	[transaction commit];
}

- (void)rollback {
	for (NSArray* array in [oldValues allValues]) {
		id object = [array objectAtIndex: 0];
		id keyPath = [array objectAtIndex: 1];
		id value = [array objectAtIndex: 2];
		[object setValue: [value isKindOfClass: [EPNil class]] ? nil : value forKeyPath: keyPath];
	}
	[[transaction retain] autorelease];
	environment.transaction = nil;
	[transaction rollback];
}

- (EXTransaction*)transaction {
	return transaction;
}

- (void)value:(id)oldValue ofObject:(id)object changedTo:(id)newValue forKeyPath:(NSString*)keyPath {
	//NSLog(@"%@ -> %@", oldValue, newValue);
	[changedObjects addObject: object];
	id key = [NSString stringWithFormat: @"%ld:%@", object, keyPath];
	if ([oldValues objectForKey: key] == nil)
		[oldValues setObject: [NSArray arrayWithObjects: object, keyPath, oldValue ?: [EPNil _nil], nil] forKey: key];
}

- (void)dealloc {
	NSLog(@"Dealloc: EPTransaction");
	[transaction release];
	[changedObjects release];
	[oldValues release];
	[super dealloc];
}

@end
